import widgetsMethods from '@/assets/widgets/widgets-methods.js'
import { Modal } from 'ant-design-vue'

export default {
  ...widgetsMethods,
  alert2(content) {
    Modal.error({ title: '提示', content });
  },
  copy(str) {
    typeof str === 'object' && (str = JSON.stringify(str, 0, 2))

    try {
      navigator.clipboard.writeText(str)
    } catch {
      const input = document.createElement('textarea')
      input.style.cssText = `
        width: 600px; height: 400px;
        position: fixed; left: 0; bottom: 110%;
      `
      input.readOnly = true
      input.value = str
      document.body.appendChild(input)
      input.focus()
      input.select()
      document.execCommand('copy')
      input.remove()
    }

    this.$root.message.success('复制成功')
  },
  formatXML(str) {
    return str?.trim() || str
  },
  formatJSON(json) {
    try {
      return JSON.stringify(typeof json === 'object' ? json : JSON.parse(json), 0, 2)
    } catch {
      return json
    }
  },
  formatSc(str = '') {
    let depth = 0
    let result = ''

    str = str.replace('SQL SECURITY ', str => str + '\n')

    for (let i = 0, len = str.length; i < len; i++) {
      const prev = i > 0 ? str[i - 1] : ''
      const next = i < len - 1 ? str[i + 1] : ''
      const s = str[i]

      switch (s) {
        case '(':
          if (prev === `'`) {
            result += s
          } else {
            depth++
            result += s + '\n' + ''.padEnd(depth * 2, ' ')
          }
          break
        case ')':
          if (next === `'`) {
            result += s
          } else {
            depth--
            result += '\n' + ''.padEnd(depth * 2, ' ') + s
          }
          break
        case ',':
          result += ',\n' + ''.padEnd(depth * 2, ' ')
          break
        case '+':
          if (prev === ` ` && next === ` `) {
            result += s + '\n' + ''.padEnd(depth * 2, ' ')
            i++
          } else {
            result += s
          }
          break
        default:
          result += s
          break
      }
    }
    
    return result
  },
  async post(url, data = {}) {
    const vm = this.$root

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()
      const fm = new FormData()
      const action = data.a
      delete data.a

      Object.keys(data).forEach((key) => {
        const val = data[key]
        if (val === undefined || val === null) return;
        fm.append(key, val)
      })

      xhr.open('POST', url + (action ? '?a=' + action : ''), true)
      xhr.send(fm)
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            let resData = xhr.responseText

            try {
              resData = JSON.parse(resData)
            } catch {
              reject(resData, xhr)
              return
            }

            if (resData.errCode) {
              switch (resData.errCode) {
                case 1:
                  vm.alert(resData.errMsg)
                  break
                case 2:
                  console.warn(url, '\n', resData.data)
                  break
              }
              reject(resData, xhr)
            } else {
              resolve(resData.data)
            }
          } else {
            const msg = {
              0: '后台似乎未开启， status: 0',
              403: '接口禁止访问，可能的原因：请求路径错误， status: 403',
              404: '接口不通， status: 404',
              500: '后台错误， status: 500',
            }[xhr.status] || '后台错误'
            vm.alert(msg)
            reject(msg, xhr)
          }
        }
      }
    })
  },
  convertCamelCase(str) {
    return (
      str.indexOf('-') > -1
        ? str.replace(/-\w/g, str => str[1].toUpperCase())
        : str.replace(/[A-Z]/g, s => '-' + s.toLowerCase())
    )
  },
  log(...arg) {
    console.log(...arg)
  },
  corPath(path) {
    return path.replace(/(\\|\/)+/g, '/')
  },
  openFile(path) {
    fetch('/__open-in-editor?file=' + encodeURIComponent(path))
  },
  initRouter() {
    const vm = this.$root
    const hash = decodeURIComponent(location.hash.substring(1))
    let r = {}
    try { r = JSON.parse(hash) } catch {}

    vm.router = r
  },
  updateRouter(r, isRouterPush = true) {
    const vm = this.$root
    vm.isRouterPush = isRouterPush
    vm.router = {
      ...vm.router,
      ...r,
    }
    setTimeout(() => delete vm.isRouterPush, 10)
  },
  setRouter(r, isRouterPush = true) {
    const vm = this.$root
    vm.isRouterPush = isRouterPush
    vm.router = r
    setTimeout(() => delete vm.isRouterPush, 10)
  },
  initEvents() {
    const vm = this.$root

    document.onkeydown = (e) => {
      if (e.target.closest('form')) return

      const sKey = vm.keyMap[e.keyCode]

      if (e.ctrlKey) {
        switch (sKey) {
          case 'y': history.forward(); break
          case 'z': history.back(); break
        }
      }
    }

    window.onpopstate = () => {
      vm.initRouter()
    }
    window.onpopstate()
  },
  init() {
    this.initEvents()
  },
}
